package compiler

type SymbolScope string

const (
	GlobalScope SymbolScope = "GLOBAL" // 全局作用域
)

type Symbol struct {
	Name  string      // 变量名
	Scope SymbolScope // 作用域
	Index int         // 索引
}

type SymbolTable struct {
	store          map[string]Symbol // 符号表
	numDefinitions int               // 总共有多少变量
}

func NewSymbolTable() *SymbolTable {
	s := make(map[string]Symbol)
	return &SymbolTable{store: s, numDefinitions: 0}
}

// 新定义一个符号
// 注意该方法不是返回指针，而是直接返回变量，因为如果返回的结果是指针的话，一旦被修改就影响到 st 变量的内部存储了，我们不希望发生这种情况，所以返回一个副本，随便修改。
func (st *SymbolTable) Define(name string) Symbol {
	ns := Symbol{
		Name:  name,
		Scope: GlobalScope,
		Index: st.numDefinitions,
	}

	st.store[name] = ns
	st.numDefinitions += 1
	return ns
}

func (st *SymbolTable) Resolve(name string) (Symbol, bool) {
	obj, ok := st.store[name]
	return obj, ok
}
